package nl.hanze.designpatterns.db;

import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * 
 * @author henderikus Harms
 *
 * @param <T>
 */
public class RowIterator<T> implements Iterator<T> {
	
	Class<T> tClass;
	ResultSet resultSet;
	
	protected RowIterator(Class<T> tClass, ResultSet resultSet){
		this.tClass = tClass;
		this.resultSet = resultSet;
	}
	
	@Override
	public boolean hasNext() {
		boolean hasNext = false;
		try{
			hasNext =  this.resultSet.next();
		} catch (SQLException e){
			e.printStackTrace();
		}
		return hasNext;
	}

	// TODO The Iterator should not rely on the resultset the whole time IMO, because it keeps the resource occupied.
	// The resultset should be completely read on the creation of this class.
	@Override
	public T next() {
		try{
			T t = tClass.newInstance();
			Method[] methods = tClass.getDeclaredMethods();
			
			for(Method method : methods){
				String methodName = method.getName();
				if (methodName.startsWith("set")){
					if(methodName.endsWith("Id")){
						int value = resultSet.getInt(methodName.substring(3));
						if(value > 0){
							t.getClass().getMethod(methodName, int.class).invoke(t, value);
						}
					}else{
						String value = resultSet.getString(methodName.substring(3));
						if(!value.isEmpty()){
							method.invoke(t, value);
						}
					}
					
				}
				
			}
			return t;
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void remove() {
		throw new UnsupportedOperationException();
	}
}
